home *** CD-ROM | disk | FTP | other *** search
- /* Functions for displaying an alert using the notification manager. Two
- functions are provided, one for use from an application and the other
- for use from an INIT.
-
- Bugs: The notification manager alert posted from an INIT allocates
- some memory in the system heap which is never disposed of. The UMPG
- contains some code which shows how to dispose of the memory, but
- I haven't incorporated it into this file.
-
- Revision History:
-
- 91/06/05 AIH
- - Fixed a few comments
-
- 91/04/21 AIH
- - Slightly changed names of the external functions
-
- 91/03/23 AIH
- - Adapted for 7.0 header files
-
- 91/03/06 AIH
- - Added support for extra response function
-
- 91/03/02 AIH
- - Added test for system 6.0
-
- 91/01/25 AIH
- - Rewrote to support small icons
-
- 91/01/20 AIH
- - Added calls to GlobalSetup and GlobalRestore
-
- 91/01/05 Ari Halberstadt (AIH)
- - Inserted this standard header in all files */
-
- #include <string.h>
- #include "MacLib.h"
- #include "MemoryLib.h"
- #include "StringLib.h"
- #include "AlertLib.h"
-
- /* A pointer to this structure is placed in the notification record's refCon
- field. It stores a pointer to the application's extra response
- function. */
- struct ExtraResponse {
- ProcPtr response;
- void *data;
- };
-
- /* load and detach the 'SICN' resource */
- static Handle LoadSicn(short sicnid)
- {
- BEGIN
- Handle sicn;
-
- sicn = GetResource('SICN', sicnid);
- if (sicn) {
- HNoPurge(sicn);
- DetachResource(sicn);
- if (ResError())
- sicn = NULL;
- }
- return(sicn);
- END
- }
-
- /* Post a notification manager alert containing the string and use the
- 'SICN' with the specified ID, or no 'SICN' if the ID is 0. The 'response'
- parameter should be the response function to call, or -1L to use
- the Notification Manager's default function. */
- static void AlertNotify(const CStr255 str, short sicnid, ProcPtr response,
- struct ExtraResponse *extra)
- {
- BEGIN
- NMRec *nm = NULL;
- StringPtr nmStr = NULL;
- Handle nmIcon = NULL;
- OSErr err = noErr;
-
- require(StrValid(str, sizeof(CStr255)));
- require(response == (ProcPtr) -1 || response != NULL);
-
- /* make sure the notification manager is available */
- if (MacHasNotificationMgr()) {
-
- /* remember base register to global variables */
- GlobalRemember();
-
- /* load the sicn if one is specified */
- if (sicnid)
- nmIcon = LoadSicn(sicnid);
-
- /* allocate notification record */
- nm = (NMRec *) NewPtrClear(sizeof(NMRec));
- err = MemError();
- if (! err) {
-
- /* allocate string */
- nmStr = (StringPtr) NewPtr(strlen(str)+1);
- err = MemError();
- if (! err) {
-
- /* fill in fields of notification record */
- CtoPstr(strcpy((char*)nmStr, str));
- nm->qType = nmType;
- nm->nmIcon = nmIcon;
- nm->nmStr = nmStr;
- nm->nmResp = response;
- nm->nmRefCon = (long) extra;
- err = NMInstall((void *) nm);
- }
- }
-
- /* cleanup */
- if (err) {
- if (nm) DisposPtr((Ptr) nm);
- if (nmStr) DisposPtr((Ptr) nmStr);
- if (nmIcon) DisposHandle((Handle) nmIcon);
- }
- }
- END
- }
-
- /* response procedure for Notification Manager */
- static pascal void NMResponse(QElemPtr qp)
- {
- BEGIN
- NMRec *nm = (NMRec *) qp;
- struct ExtraResponse *extra;
-
- /* setup base register to global variables */
- GlobalSetup();
-
- /* remove notification */
- if (NMRemove((void *) nm) == noErr) {
-
- /* get extra response function */
- extra = (struct ExtraResponse *) nm->nmRefCon;
- if (extra) {
-
- /* call extra response function and dispose of extra pointer */
- extra->response(extra->data);
- DisposPtr((Ptr) extra);
- }
-
- /* dispose of notification */
- if (nm->nmStr)
- DisposPtr((Ptr) nm->nmStr);
-
- if (nm->nmIcon)
- DisposHandle((Handle) nm->nmIcon);
-
- DisposPtr((Ptr) nm);
- }
-
- /* restore base register to global variables */
- GlobalRestore();
- END
- }
-
- /* Use Notification Manager to display an alert containing the given
- string. If 'sicnid' is non-zero then a 'SICN' resource with the
- id is loaded and installed in the notification. If the 'response'
- parameter is non-null, it should contain a pointer to a function
- which will be called just after the notification has been removed
- from the queue. This "extra" response function should be declared
- as follows:
-
- void response(void *data)
-
- The 'data' parameter may contain anything the application puts in it,
- sinze it will be passed to the extra response function. */
- void AlertNotification(const CStr255 str, short sicnid, ProcPtr response,
- void *data)
- {
- BEGIN
- struct ExtraResponse *extra;
-
- require(StrValid(str, sizeof(CStr255)));
-
- /* create extra response structure */
- extra = NULL;
- if (response) {
- extra = (struct ExtraResponse *) NewPtr(sizeof(struct ExtraResponse));
- if (extra) {
- extra->response = response;
- extra->data = data;
- }
- }
- AlertNotify(str, sicnid, (ProcPtr) NMResponse, extra);
- END
- }
-
- /* same as AlertNotification but works with an INIT */
- void AlertNotificationINIT(const CStr255 str, short sicnid)
- {
- BEGIN
- THz oldzone;
-
- require(StrValid(str, sizeof(CStr255)));
-
- /* set current zone to System zone so that all the memory allocated will be
- around even after the INIT has exited; this causes some wasted space, but
- there's no simple way around this problem */
- oldzone = (THz) GetZone();
- SetZone(SystemZone());
-
- /* post the notification using the default response procedure since
- the INIT's code won't be around by the time the response procedure
- is called */
- AlertNotify(str, sicnid, (ProcPtr) -1, NULL);
-
- /* restore old heap zone */
- SetZone(oldzone);
- END
- }
-
-